package com.mozilla.bespin; import org.json.simple.JSONObject; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class SessionTracker { private Map<File, List<EditSession>> sessionsByFile = new HashMap<File, List<EditSession>>(); private Map<UserSession, List<EditSession>> sessionsByUser = new HashMap<UserSession, List<EditSession>>(); /** * Returns the edits that a user has applied to a specified file. * * @param file * @param session * @return always returns a list; if no edits have been applied, an empty list is returned. The returned list is not live. */ public synchronized List<JSONObject> getEdits(File file, UserSession session) { EditSession editSession = getSession(file, session); return (editSession != null) ? editSession.getEdits() : Collections.EMPTY_LIST; } /** * Returns any edit sessions that may be open for this file; returned list is not live * * @return */ public synchronized List<EditSession> getSessions(File file) { return new ArrayList<EditSession>(getLiveSessions(file)); } /** * Returns any edit sessions open by the passed user; returned list is not live * @param user * @return */ public synchronized List<EditSession> getSessions(UserSession user) { return new ArrayList<EditSession>(getLiveSessions(user)); } /** * Returns the EditSession corresponding to the passed UserSession, or null if one does not exist * * @param file * @param session * @return */ public synchronized EditSession getSession(File file, UserSession session) { List<EditSession> editSessions = sessionsByFile.get(file); if (editSessions == null) return null; for (EditSession editSession : editSessions) { if (editSession.getUser().equals(session)) return editSession; } return null; } public synchronized EditSession openSession(File file, UserSession session, EditMode mode) { if (getSession(file, session) != null) throw new ConcurrentModificationException("Edit session already exists"); EditSession editSession = new EditSession(file, session, mode); getLiveSessions(file).add(editSession); getLiveSessions(session).add(editSession); return editSession; } public synchronized void closeSession(File file, UserSession session) { EditSession edit = getSession(file, session); if (edit != null) { getLiveSessions(file).remove(edit); getLiveSessions(session).remove(edit); } } public synchronized void resetEdits(File file) { List<EditSession> edits = getLiveSessions(file); for (EditSession edit : edits) { edit.clearEdits(); } } public synchronized void resetEdits() { Collection<List<EditSession>> edits = sessionsByFile.values(); for (Iterator<List<EditSession>> iterator = edits.iterator(); iterator.hasNext();) { List<EditSession> lists = iterator.next(); for (EditSession edit : lists) { edit.clearEdits(); } } } private synchronized List<EditSession> getLiveSessions(UserSession user) { List<EditSession> sessions = this.sessionsByUser.get(user); if (sessions == null) { sessions = new ArrayList<EditSession>(); this.sessionsByUser.put(user, sessions); } return sessions; } private synchronized List<EditSession> getLiveSessions(File file) { List<EditSession> sessions = this.sessionsByFile.get(file); if (sessions == null) { sessions = new ArrayList<EditSession>(); this.sessionsByFile.put(file, sessions); } return sessions; } }